package controller;

import entity.IndirizzoAbitazione;
import entity.UtenteRegistrato;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import sbForEntityClasses.IndirizzoAbitazioneFacadeLocal;
import sbForEntityClasses.IndirizzoEmailFacadeLocal;
import sbForEntityClasses.UtenteRegistratoFacadeLocal;
import utilities.googleMap.DistanceMatrix;

/**
 * Operazioni generiche sugli utenti
 * @author ale
 */
@Stateless
public class ControllerUtenti implements ControllerUtentiLocal {

    @EJB
    private ControllerComuniLocal controllerComuni;
    @EJB
    private IndirizzoAbitazioneFacadeLocal indirizzoAbitazioneFacade;
    @EJB
    private IndirizzoEmailFacadeLocal indirizzoEmailFacade;
    @EJB
    private UtenteRegistratoFacadeLocal utenteRegistratoFacade;
    @PersistenceContext(unitName = "ShippingShareBisBis-ejbPU")
    private EntityManager em;

    /**
     * Crea un indirizzo e lo inserisce nal database
     * @param indirizzo descrizione dell'indirizzo (es. "Via Mazzini 12, Rapallo")
     * @return l'indirizzo creato
     */
    @Override
    public IndirizzoAbitazione creaIndirizzo(String indirizzo) {
        IndirizzoAbitazione abitazione = new IndirizzoAbitazione(indirizzo);
        abitazione.setDescrizione(indirizzo);
        String comune = DistanceMatrix.getLocality(indirizzo);
        abitazione.setRegione(controllerComuni.getRegion(comune));
        indirizzoAbitazioneFacade.create(abitazione);
        return abitazione;
    }

    /**
     * Restituisce il numero totale di utenti presenti nel sistema
     * @return il numero totale di utenti presenti nel sistema
     */
    @Override
    public int getNumeroUtenti() {
        return utenteRegistratoFacade.count();
    }

    /**
     * Restituisce il numero di indirizzi e-mail in totale presenti nel sistema
     * @return il numero di indirizzi e-mail in totale presenti nel sistema
     */
    @Override
    public int getNumeroMail() {
        return indirizzoEmailFacade.count();
    }

    /**
     * Restituisce il numero di indirizzi di abitazione in totale presenti nel sistema
     * @return il numero di indirizzi di abitazione in totale presenti nel sistema
     */
    @Override
    public int getNumeroAbitazioni() {
        return indirizzoAbitazioneFacade.count();
    }

    /**
     * Persistenza
     * @param object
     */
    public void persist(Object object) {
        em.persist(object);
    }

    /**
     * Recupera un utente a partire dall'id specificato
     * @param id l'id dell'utente cercato
     * @return l'utente corrispondente, se esiste; null altrimenti
     */
    @Override
    public UtenteRegistrato getUtenteById(long id) {
        return utenteRegistratoFacade.find(id);
    }

    /**
     * Verifica se esiste un utente con la mail specificata
     * @param mail la mail cercata
     * @return true sse esiste un utente con la mail specificata
     */
    @Override
    public boolean isRegistrato(String mail) {
        String query = "SELECT x FROM UtenteRegistrato x WHERE x.indirizzoEmail.indirizzo = ?1";
        Query q = em.createQuery(query);
        q.setParameter(1, mail);
        try {
            UtenteRegistrato ur = (UtenteRegistrato) q.getSingleResult();
            return true;
        } catch (NoResultException nre) {
            return false;
        }
    }

    /**
     * Recupera un utente basandosi sull'indirizzo e-mail con cui si è registrato
     * @param mail l'indirizzo e-mail dell'utente cercato
     * @return l'utente, se esiste; null altrimenti
     */
    @Override
    public UtenteRegistrato getUserByMail(String mail) {
        String query = "SELECT x FROM UtenteRegistrato x WHERE lower(x.indirizzoEmail.indirizzo) LIKE lower(?1)";
        Query q = em.createQuery(query);
        q.setParameter(1, mail);
        try {
            UtenteRegistrato ur = (UtenteRegistrato) q.getSingleResult();
            return ur;
        } catch (NoResultException nre) {
            return null;
        }
    }

    /**
     * Restituisce la lista di tutti gli utenti presenti nel sistema
     * @return la lista di tutti gli utenti presenti nel sistema
     */
    @Override
    public List<UtenteRegistrato> getAllUtenti() {
        return utenteRegistratoFacade.findAll();
    }
    
}
